package service

import (
	"strings"

	jsoniter "github.com/json-iterator/go"
	"zhonghui/console/warehouse/dbx/db_zh_kernel"
	"zhonghui/console/warehouse/helperx"
	"zhonghui/console/warehouse/logx"

	"zhonghui/console/warehouse/modelx/model_zh_kernel"

	"zhonghui/console/structs"
)

// CanDo 检查用户是否有某项特定权限
func CanDo(userId uint, action string) bool {
	policies, err := GetUserPolicies(userId)
	if err != nil {
		return false
	}

	logx.Zap().Infow("权限列表",
		"user_id", userId,
		"action", action,
		"policies", policies,
	)

	// 拆分权限
	actionParams := strings.Split(action, ":")

	for _, policy := range policies {
		// 解析权限配置
		conf := structs.PolicyConf{}
		if err := jsoniter.UnmarshalFromString(policy.Conf, &conf); err != nil {
			return false
		}

		// 循环action列表
		for _, a := range conf.Action {
			// 检查全部操作
			if a == "*:*" {
				return conf.Effect == "allow"
			}

			// 拆分操作名
			policyActionParams := strings.Split(a, ":")

			// 操作名一样，开始检查
			if policyActionParams[0] == actionParams[0] {
				// 开始检查是否为整个模块的全局操作
				if policyActionParams[1] == "*" {
					return conf.Effect == "allow"
				}

				// 检查特定操作
				if policyActionParams[1] == actionParams[1] {
					return conf.Effect == "allow"
				}
			}
		}
	}

	return false
}

// GetUserPolicies 获取当前用户的全部权限明细
func GetUserPolicies(userId uint) ([]model_zh_kernel.ConsolePolicies, error) {
	policies := make([]model_zh_kernel.ConsolePolicies, 0)

	policyIds, err := GetUserPolicyIds(userId)
	if err != nil {
		return policies, err
	}

	if err := db_zh_kernel.Client().Where("id in (?)", policyIds).Find(&policies).Error; err != nil {
		return policies, err
	}

	return policies, nil
}

// IsAdmin 是否为超级管理员
func IsAdmin(userId uint) bool {
	policyIds, err := GetUserPolicyIds(userId)
	if err != nil {
		return false
	}

	return db_zh_kernel.Client().Where("id in (?) and code = 'AdminFullAccess'", policyIds).Take(&model_zh_kernel.ConsolePolicies{}).Error == nil
}

// IsNormalAdmin 是否为普通管理员
func IsNormalAdmin(userId uint) bool {
	// return false
	return IsAdmin(userId) || db_zh_kernel.Client().Where("manager_id = ? and group_id = 2", userId).Take(&model_zh_kernel.ConsoleGroupManager{}).Error == nil
}

// GetUserPolicyIds 获取当前用户的权限，包括归属用户组的权限的集合
func GetUserPolicyIds(userId uint) ([]int, error) {
	policyIds := make([]int, 0)

	// 查询用户所属用户组的id
	ids := make([]uint, 0)
	groups := make([]model_zh_kernel.ConsoleGroupManager, 0)
	if err := db_zh_kernel.Client().Where("manager_id = ?", userId).Find(&groups).Error; err != nil {
		return policyIds, err
	}
	for _, group := range groups {
		ids = append(ids, group.GroupID)
	}

	// 查询组的权限
	groupPermissions := make([]model_zh_kernel.ConsolePermissions, 0)
	if err := db_zh_kernel.Client().Where("entity = 'group' and entity_id in (?)", ids).Find(&groupPermissions).Error; err != nil {
		return policyIds, err
	}

	// 遍历组的权限
	for _, groupPermission := range groupPermissions {
		if !helperx.IntInArray(int(groupPermission.PolicyID), policyIds) {
			policyIds = append(policyIds, int(groupPermission.PolicyID))
		}
	}

	// 查询用户的权限
	managerPermissions := make([]model_zh_kernel.ConsolePermissions, 0)
	if err := db_zh_kernel.Client().Where("entity = 'manager' and entity_id = ?", userId).Find(&managerPermissions).Error; err != nil {
		return policyIds, err
	}

	// 遍历用户的权限
	for _, managerPermission := range managerPermissions {
		if !helperx.IntInArray(int(managerPermission.PolicyID), policyIds) {
			policyIds = append(policyIds, int(managerPermission.PolicyID))
		}
	}

	return policyIds, nil
}
